グラフィックス
Graphicsクラスには点を描く DrawPiexl()と云った明確なメソッドはないようです。したがって、ビットマップオブジェクトで点を生成して GraphicsクラスのDrawImage()メソッドを 使って点を描きました。以下に例を紹介します。 下記のプログラムは、座標(100,100)、座標(150,150)〜(151,151)、座標(200,200)〜(202,202)に それぞれ1ピクセル、4ピクセル、9ピクセルの点を描画したプログラムです。 |
実行結果 | |
<プログラム例> //フォーム全体の大きさのビットマップオブジェクトを作成した場合 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace pointDraw { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { Graphics g = this.CreateGraphics(); //グラフィックスオブジェクト生成 Bitmap bmp = new Bitmap(this.Width,this.Height); //フォームサイズのビットマップオブジェクト生成 bmp.SetPixel(0, 0, Color.Blue); //SetPixel(x,y,色)//ビットマップオブジェクトの座標(0,0)の位置に青色の点を生成 g.DrawImage(bmp,100,100); //ビットマップオブジェクトを座標(100,100)を基点として描画 g.DrawImage(bmp, 150, 150); //ビットマップオブジェクトを座標(150,150)を基点として描画 g.DrawImage(bmp, 151, 150); //ビットマップオブジェクトを座標(151,150)を基点として描画 g.DrawImage(bmp, 150, 151); //ビットマップオブジェクトを座標(150,151)を基点として描画 g.DrawImage(bmp, 151, 151); //ビットマップオブジェクトを座標(151,151)を基点として描画 g.DrawImage(bmp, 200, 200); //ビットマップオブジェクトを座標(200,200)を基点として描画 g.DrawImage(bmp, 201, 200); //ビットマップオブジェクトを座標(201,200)を基点として描画 g.DrawImage(bmp, 202, 200); //ビットマップオブジェクトを座標(202,200)を基点として描画 g.DrawImage(bmp, 200, 201); //ビットマップオブジェクトを座標(200,201)を基点として描画 g.DrawImage(bmp, 201, 201); //ビットマップオブジェクトを座標(201,201)を基点として描画 g.DrawImage(bmp, 202, 201); //ビットマップオブジェクトを座標(202,201)を基点として描画 g.DrawImage(bmp, 200, 202); //ビットマップオブジェクトを座標(200,202) を基点として描画 g.DrawImage(bmp, 201, 202); //ビットマップオブジェクトを座標(201,202)を基点として描画 g.DrawImage(bmp, 202, 202); //ビットマップオブジェクトを座標(202,202)を基点として描画 } private void Form1_Paint(object sender, PaintEventArgs e) { Graphics g = this.CreateGraphics(); //SetPixel(x,y,色)//ビットマップオブジェクトの座標(0,0)の位置に青色の点を生成 Bitmap bmp = new Bitmap(this.Width, this.Height); bmp.SetPixel(0, 0, Color.Red); g.DrawImage(bmp, 50, 50); } } }
|
![]() |
|
<プログラム例> //サイズ(1,1)のビットマップオブジェクトを作成した場合 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace drawPoint__1_1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { Graphics g = this.CreateGraphics(); //Form1へのGraphicsオブジェクトを作成 Bitmap bmp = new Bitmap(1, 1); //サイズが1ドット×1ドットのBitmapオブジェクトを作成 bmp.SetPixel(0, 0, Color.Blue); //座標(0,0)を赤色に設定 g.DrawImageUnscaled(bmp, 100, 100); //ビットマップオブジェクトを座標(100,100)を基点として描画 g.DrawImageUnscaled(bmp, 150, 150); //ビットマップオブジェクトを座標(150,150)を基点として描画 g.DrawImageUnscaled(bmp, 151, 150); //ビットマップオブジェクトを座標(151,150)を基点として描画 g.DrawImageUnscaled(bmp, 150, 151); //ビットマップオブジェクトを座標(150,151)を基点として描画 g.DrawImageUnscaled(bmp, 151, 151); //ビットマップオブジェクトを座標(151,151)を基点として描画 g.DrawImageUnscaled(bmp, 200, 200); //ビットマップオブジェクトを座標(200,200)を基点として描画 g.DrawImageUnscaled(bmp, 201, 200); //ビットマップオブジェクトを座標(201,200)を基点として描画 g.DrawImageUnscaled(bmp, 202, 200); //ビットマップオブジェクトを座標(202,200)を基点として描画 g.DrawImageUnscaled(bmp, 200, 201); //ビットマップオブジェクトを座標(200,201)を基点として描画 g.DrawImageUnscaled(bmp, 201, 201); //ビットマップオブジェクトを座標(201,201)を基点として描画 g.DrawImageUnscaled(bmp, 202, 201); //ビットマップオブジェクトを座標(202,201)を基点として描画 g.DrawImageUnscaled(bmp, 200, 202); //ビットマップオブジェクトを座標(200,202) を基点として描画 g.DrawImageUnscaled(bmp, 201, 202); //ビットマップオブジェクトを座標(201,202)を基点として描画 g.DrawImageUnscaled(bmp, 202, 202); //ビットマップオブジェクトを座標(202,202)を基点として描画 } private void Form1_Paint(object sender, PaintEventArgs e) { Graphics g = this.CreateGraphics(); //Form1へのGraphicsオブジェクトを作成 Bitmap bmp = new Bitmap(1, 1); //サイズが1ドット×1ドットのBitmapオブジェクトを作成 bmp.SetPixel(0, 0, Color.Red); g.DrawImage(bmp, 50, 50); } } } |
ピクチャーボックスのCreateGraphics()メソッドからグラフィックスのオブジェクトを生成し、描画する方法です。 但し、この方法は再描画はされないので フォームサイズ変更、背面化等で図形が消えると再描画はされません。 |
実行結果 |
|
<プログラム例> using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Drawing.Drawing2D; //点線、破線を使う場合必要 namespace drawLineCircle { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { Graphics g = pictureBox1.CreateGraphics(); //pictureBox1のCreateGraphics()メソッドからオブジェクトを生成 g.DrawLine(Pens.Black, 0, 30, pictureBox1.Width, 60); // 普通の黒色直線 点1(0,30) 点2(右端,30) g.DrawLine(Pens.Black, 0, 60, pictureBox1.Width, 30); // 普通の黒色直線 点1(0,60) 点2(右端,30) Pen boldPen = new Pen(Color.Red, 5); // 太い線赤線オブジェクト生成 g.DrawLine(boldPen, 0, 90, pictureBox1.Width, 90); //点1(0,90) 点2(右端,90) Pen dotPen = new Pen(Color.Blue, 5); //青色、線幅5 dotPen.DashStyle = DashStyle.Dot; // 点線 g.DrawLine(dotPen, 0, 110, pictureBox1.Width, 110); dotPen.DashStyle = DashStyle.DashDot; //1点鎖線 g.DrawLine(dotPen, 0, 140, pictureBox1.Width, 140); dotPen.DashStyle = DashStyle.DashDotDot; //2点鎖線 g.DrawLine(dotPen, 0, 170, pictureBox1.Width, 170); // g.DrawEllipse(Pens.Red, 65, 220, 75,75); //赤線 基点(65,220) 幅×高さ:100×50 g.FillEllipse(Brushes.Green, 65, 320, 75, 75); //赤色塗りつぶし 基点(65,220) 幅×高さ:100×50 g.DrawRectangle(Pens.Black, 50, 400, 100, 50); // 四角形を描画する //黒線、基点(50.400)、幅×高さ:100×50 g.FillRectangle(Brushes.Red, 50, 470, 100, 50); // 塗り潰しの四角形を描画する//赤色塗潰し 基点(50,470)、幅×高さ:100×50 } } } |
![]() |
描いた図形がフォームサイズの変更や他のウィンドウの背面になり隠れても、 再描画が自動的に行われもとの図形が表示できる例を以下に紹介します。 |
実行結果 | |
<プログラム例> using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Drawing.Drawing2D; //点線、破線を使う場合必要 namespace drawAgain { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Paint(object sender, PaintEventArgs e) { Graphics g = e.Graphics; // //Paintイベントから提供されるGraphicsを使用しオブジェクトを生成 // Graphics g = pictureBox1.CreateGraphics(); //隠れたあと再描画されない g.DrawEllipse(Pens.Red, 0, 0, 100, 50); //赤線 基点(0,0) 幅×高さ:100×50 g.FillEllipse(Brushes.Green, 50, 50, 100, 50); //赤色塗りつぶし 基点(50,50) 幅×高さ:100×50 } private void button1_Click(object sender, EventArgs e) { pictureBox1.Image = new Bitmap(pictureBox1.Width, pictureBox1.Height); //pictureBox1のイメージデータのオブジェクト生成 Graphics g = Graphics.FromImage(pictureBox1.Image); //イメージからグラフィックスを作成 g.DrawLine(Pens.Black, 0, 30, pictureBox1.Width, 60); // 普通の黒色直線 点1(0,30) 点2(右端,30) g.DrawLine(Pens.Black, 0, 60, pictureBox1.Width, 30); // 普通の黒色直線 点1(0,60) 点2(右端,30) Pen boldPen = new Pen(Color.Red, 5); // 太い線赤線オブジェクト生成 g.DrawLine(boldPen, 0, 90, pictureBox1.Width, 90); //点1(0,90) 点2(右端,90) Pen dotPen = new Pen(Color.Blue, 5); //青色、線幅5 dotPen.DashStyle = DashStyle.Dot; // 点線 g.DrawLine(dotPen, 0, 110, pictureBox1.Width, 110); dotPen.DashStyle = DashStyle.DashDot; //1点鎖線 g.DrawLine(dotPen, 0, 140, pictureBox1.Width, 140); dotPen.DashStyle = DashStyle.DashDotDot; //2点鎖線 g.DrawLine(dotPen, 0, 170, pictureBox1.Width, 170); // g.DrawEllipse(Pens.Red, 65, 220, 75, 75); //赤線 基点(65,220) 幅×高さ:100×50 g.FillEllipse(Brushes.Green, 65, 320, 75, 75); //赤色塗りつぶし 基点(65,220) 幅×高さ:100×50 g.DrawRectangle(Pens.Black, 50, 400, 100, 50); // 四角形を描画する //黒線、基点(50.400)、幅×高さ:100×50 g.FillRectangle(Brushes.Red, 50, 470, 100, 50); // 塗り潰しの四角形を描画する//赤色塗潰し 基点(50,470)、幅×高さ:100×50 } } } |
![]() |
円形ランプの色をボタンクリックで変更する例です。 VC#2013以降 Shapeがサポートされなくなったの代用として使っています。 |
実行結果 | |
using System; |
![]() ![]() |
|
追加されたフォーム上のピクチャーボックスのPaintイベントから提供されるGraphicsを使用し描画することにより、 追加したフォームに何の操作なしでも描画することができます。 |
実行結果 | |
<プログラム例> //Form1 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace drawAddedFormNoAct { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { Form2 form2 = new Form2(); form2.ShowDialog(); } } } //------------------------------------------------------------------------------ //Form2 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace drawAddedFormNoAct { public partial class Form2 : Form { public Form2() { InitializeComponent(); } private void pictureBox1_Paint(object sender, PaintEventArgs e) { Graphics g = e.Graphics; //Paintイベントから提供されるGraphicsを使用しオブジェクトを生成 // Graphics g = pictureBox1.CreateGraphics();//このオブジェクトでは描けない // 四角形を描画する g.DrawRectangle(Pens.Black, 0, 0, 100, 50); //黒線、基点(0.0)、幅×高さ:100×50 // 塗り潰しの四角形を描画する g.FillRectangle(Brushes.Red, 50, 75, 100, 50); //赤色塗潰し 基点(50,75)、幅×高さ:100×50 } } } |
![]() |
■ 正弦波形を描く
正弦関数は Math.sin( )、Π( = 3.1416…)は、Math.PI で呼び出します |
実行結果 | |
<プログラム例> using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace sinDraw { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void pictureBox1_Paint(object sender, PaintEventArgs e) { int i, j,j0; int x0 = 0, y0 = 150; //原点座標 double angle; //角度 Graphics g = e.Graphics; //フォームサイズのビットマップオブジェクト生成 Bitmap bmp = new Bitmap(pictureBox1.Width,pictureBox1.Height); //原点:(x0,y0) g.DrawLine(Pens.Black, x0, y0, 720, y0); //横軸 中央:150 g.DrawLine(Pens.Black, 0, y0 +100, 0, y0 - 100); //原点の縦軸 for (i = 0; i < 8; i++) //横軸目盛(90゜間隔) { g.DrawLine(Pens.Black, 90 * (i + 1), y0 + 10, 90 * (i + 1), y0 - 10); } for (j = 0; j < 720; j++) //0〜720゜正弦波形作成 { if (j >= 360) j0 = j - 360; else j0 = j; //while (true) //無限ループ抜けられず //{ // if (j <= 360) // { // j0 = j; // break; // } // else // { // j = j - 360; // } //} angle = ((double)j0) / 360 * 2 * Math.PI; //角度 //点の設定 bmp.SetPixel(j, (int)(100 * Math.Sin(angle) + 150), Color.Red); } //ビットマップオブジェクトの基点をピクチャーボックスの左上に設定 g.DrawImage(bmp,0, 0); } } } |
![]() |
|
■ 文字を描画する
DrawString()メソッドにより、文字を描画することもできます。 | 実行結果 | |
<プログラム例> using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace pictureBox_text { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void PictureBoxSWView_Paint(object sender, PaintEventArgs e) { Graphics g = e.Graphics; Pen objPen = new Pen(System.Drawing.Color.Blue, 2); Font objFont = new Font("MS Pゴシック", 15); g.DrawString("描画テスト_Paint", objFont, Brushes.Red, 0,0); } private void button1_Click(object sender, EventArgs e) { Pen objPen = new Pen(System.Drawing.Color.Blue, 2); Font objFont = new Font("MS Pゴシック", 15); Graphics objGrp = pictureBox1.CreateGraphics(); // 文字を描画する objGrp.DrawString("描画テスト_btnClick", objFont, Brushes.Blue, 0, 30); // リソースを解放する objPen.Dispose(); objFont.Dispose(); objGrp.Dispose(); } } } |
![]() |
ピクチャーボックスやフォームのRefresh( )メソッドで必要な時にPaintイベントの再描画ができます。 下記のプログラムはタイマでカウントアップした直後にピクチャボックスを再描画しています。 実行結果は1秒毎にカウントの数値の増加を示しています。 |
実行結果 | |
<プログラム例> using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace timeChange_PicBox { public partial class Form1 : Form { int Count = 0; public Form1() { InitializeComponent(); } private void pictureBox1_Paint(object sender, PaintEventArgs e) { Graphics g = e.Graphics; Pen objPen = new Pen(System.Drawing.Color.Blue, 4); Font objFont = new Font("MS Pゴシック", 60); String str = Count.ToString(); g.DrawString(str, objFont, Brushes.Red, 0, 0); } private void timer1_Tick(object sender, EventArgs e) { Count++; pictureBox1.Refresh(); //直ちに再描画 } } } |
![]() 起動時 ![]() 1秒後 ![]() 2秒後 ・ ・ ・ |
以下のイベントで再描画が発生します。 ボタン: イベントはフォーカス enter/leave、クリックpress/remove で発生 テキストボックス: フォーカス時の enter/removeで発生 |
実行結果 | |
using System; |
![]() <ボタンフォーカス leaveの場合> ![]() <ボタンフォーカス enterの場合> ![]() <フォーカス時のテキストボックス enterの場合> |
■ USBコネクタ抜き差しのイベントによる再描画
精度のいらない簡単な図形をフリーハンドで描く場合、shapeは大変便利です。 | 実行結果 | |
<プログラム例> using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace panel_shape { public partial class Form1 : Form { public Form1() { InitializeComponent(); //コードで描く場合 //lineShape //lineShape1.BorderColor = Color.Red; //赤色 //lineShape1.BorderWidth = 8; //線幅:8 //lineShape1.X1 = 184; //lineShape1.Y1 = 294; //lineShape1.X2 = 290; //lineShape1.Y2 = 120; //ovalShape //ovalShape1.BorderColor = Color.Blue; //青色 //ovalShape1.BorderWidth = 5; //線幅:5 //ovalShape1.Location = new Point(50,50); //基点(左上)設定 //System.Drawing.Size sz = new System.Drawing.Size(100,100); //直径100 //ovalShape1.Size = sz; //rectangleShape //rectangleShape1.BorderColor = Color.Black; // rectangleShape1.FillStyle = FillStyle.Solid; // なぜかコンパイルできない。 バグ? } } } |
![]() |
フォームの背景は、g.Clear(BackColor)で;クリアできます。 クリア後、Paintイベントで描いた初期設定を実施したい場合は this.Refresh( )でできます。 背景色の設定はg.Clear(Color.XXX )で設定できます。 以下は プログラムの例です。 |
実行結果 |
|
<プログラム例> using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace formRefresh { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Paint(object sender, PaintEventArgs e) { Graphics g = e.Graphics; // //Paintイベントから提供されるGraphicsを使用しオブジェクトを生成 // Graphics g = pictureBox1.CreateGraphics(); //隠れたあと再描画されない g.DrawEllipse(Pens.Red, 0, 0, 100, 50); //赤線 基点(0,0) 幅×高さ:100×50 g.FillEllipse(Brushes.Green, 50, 50, 100, 50); //赤色塗りつぶし 基点(50,50) 幅×高さ:100×50 } private void button1_Click(object sender, EventArgs e) //背景クリア { Graphics g = this.CreateGraphics(); g.Clear(BackColor); } private void button2_Click(object sender, EventArgs e) //フォームクリア //フォームがクリアされた後にForm1_Paint()が実行される { this.Refresh(); } private void button3_Click(object sender, EventArgs e) //背景色設定 { Graphics g = this.CreateGraphics(); g.Clear(Color.Gold); //背景色を金色に設定 } } } |
![]() 起動画面 ![]() button1 クリック後 ![]() button2クリック後 ![]() button3クリック後 |